﻿
Imports System.Threading
Imports System.Net
Imports System.Net.Sockets
Imports osi.root.connector
Imports osi.root.formation
Imports osi.root.procedure
Imports osi.root.constants
Imports osi.root.utils
Imports osi.root.lock

Partial Public Class connection_manager
    Private Shared ReadOnly m As map(Of String, powerpoint)
    Private Shared l As duallock

    Shared Sub New()
        assert(DirectCast(Nothing, Boolean) = False)
        assert(DirectCast(Nothing, powerpoint) Is Nothing)
        assert(DirectCast(Nothing, Int64) = 0)
        m = New map(Of String, powerpoint)()
        application_lifetime.stopping_handle(Sub()
                                                 l.reader_locked(
                                                     Sub()
                                                         Dim it As map(Of String, powerpoint).iterator = Nothing
                                                         it = m.begin()
                                                         While it <> m.end()
                                                             With (+it)
                                                                 .second.close()
                                                             End With
                                                             it += 1
                                                         End While
                                                     End Sub)
                                                 GC.KeepAlive(l)
                                                 GC.KeepAlive(m)
                                             End Sub)
    End Sub

    Public Shared Function is_valid_name(ByVal n As String) As Boolean
        Return Not String.IsNullOrEmpty(n)
    End Function

    Private Shared Function get_powerpoint(Of T)(ByVal name As String, ByVal d As Func(Of powerpoint, T)) As T
        assert(Not d Is Nothing)
        If Not is_valid_name(name) Then
            Return Nothing
        Else
            Return l.reader_locked(Function() As T
                                       Dim it As map(Of String, powerpoint).iterator = Nothing
                                       it = m.find(name)
                                       If it = m.end() Then
                                           Return Nothing
                                       Else
                                           With (+it)
                                               assert(Not .second Is Nothing)
                                               If .second.expired() Then
                                                   Return Nothing
                                               Else
                                                   Return d(.second)
                                               End If
                                           End With
                                       End If
                                   End Function)
        End If
    End Function

    Public Shared Function [get](ByVal name As String,
                                 ByRef p As powerpoint) As Boolean
        Dim t As powerpoint = Nothing
        Return get_powerpoint(name, Function(x) eva(t, x)) AndAlso
               eva(p, t)
    End Function

    Public Shared Function expired(ByVal name As String) As Boolean
        Return get_powerpoint(name, Function(x) x.expired())
    End Function

    Public Shared Function connected_count(ByVal name As String) As Int64
        Return get_powerpoint(name, Function(x) x.connected_count())
    End Function

    Public Shared Function free_connection_count(ByVal name As String) As Boolean
        Return get_powerpoint(name, Function(x) x.free_count())
    End Function

    Public Shared Function [get](ByVal name As String,
                                 ByRef r As TcpClient,
                                 Optional ByRef ppt As powerpoint = Nothing) As Boolean
        Dim c As TcpClient = Nothing
        Dim p As powerpoint = Nothing
        Return get_powerpoint(name, Function(x) eva(p, x) AndAlso x.get(c)) AndAlso
               eva(ppt, p) AndAlso
               eva(r, c)
    End Function

    Public Shared Function release(ByVal name As String, ByVal c As TcpClient) As Boolean
        Return get_powerpoint(name, Function(x) x.release(c))
    End Function

    Public Shared Function [get](ByVal name As String,
                                 ByVal c As pointer(Of TcpClient),
                                 Optional ByVal timeout_ms As Int64 = npos,
                                 Optional ByVal ppt As pointer(Of powerpoint) = Nothing) As event_comb
        Dim r As pointer(Of Boolean) = Nothing
        Return New event_comb(Function() As Boolean
                                  If is_valid_name(name) Then
                                      r = New pointer(Of Boolean)()
                                      Return waitfor(Function() As Boolean
                                                         Dim cc As TcpClient = Nothing
                                                         Dim p As powerpoint = Nothing
                                                         Return [get](name, cc, p) AndAlso
                                                                eva(ppt, p) AndAlso
                                                                eva(c, cc)
                                                     End Function,
                                                     r,
                                                     timeout_ms) AndAlso
                                             goto_next()
                                  Else
                                      Return False
                                  End If
                              End Function,
                              Function() As Boolean
                                  Return (+r) AndAlso
                                         goto_end()
                              End Function)
    End Function
End Class
